package cn.wolfcode.wms.service.impl;

import cn.wolfcode.wms.domain.Permission;
import cn.wolfcode.wms.mapper.PermissionMapper;
import cn.wolfcode.wms.page.PageResult;
import cn.wolfcode.wms.qo.QueryObject;
import cn.wolfcode.wms.service.IPermissionService;
import cn.wolfcode.wms.util.RequiredPermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class PermissionServiceImpl implements IPermissionService {

    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private ApplicationContext ctx;

    public List<Permission> listAll() {
        return permissionMapper.selectAll();
    }

    public Permission getById(Long id) {
        return permissionMapper.selectByPrimaryKey(id);
    }

    public void saveOrUpdate(Permission permission) {
        if (permission.getId() != null) {
            permissionMapper.updateByPrimaryKey(permission);
        } else {
            permissionMapper.insert(permission);
        }
    }

    public void delete(Long id) {
        permissionMapper.deleteByPrimaryKey(id);
    }

    public PageResult query(QueryObject qo) {
        int rows = permissionMapper.queryForCount(qo);
        if(rows==0){
            return PageResult.empty(qo.getPageSize());
        }
        List<?> result= permissionMapper.queryForList(qo);
        return new PageResult(rows, result,qo.getCurrentPage(),qo.getPageSize());
    }

    public void load() {
        // 先获取到系统已有的所有权限
        List<Permission> permissions = permissionMapper.selectAll();
        Set<String> expressions = new HashSet<>();
        // 将这些权限对象的表达式，封装到set集合中，去重
        for (Permission permission : permissions) {
            expressions.add(permission.getExpression());
        }

        // 1. 获取到所有贴有 controller 注解的 bean
        Map<String, Object> objectMap = ctx.getBeansWithAnnotation(Controller.class);
        // 2. 遍历这些bean，获取到每一个bean对应的所有方法
        for (Object bean : objectMap.values()) {
            // 3. 遍历方法，判断当前方法是否贴有权限注解
            Method[] methods = bean.getClass().getDeclaredMethods();
            for (Method method : methods) {
                // 4. 如果有创建一个权限类，拼接权限表达式，封装权限对象
                if (method.isAnnotationPresent(RequiredPermission.class)) {
                    // 拼接权限表达式
                    String expression = bean.getClass().getName() + ":" + method.getName();

                    // 判断当前系统中是否已经存在该表达式
                    if (!expressions.contains(expression)) {

                        // 获取权限注解
                        RequiredPermission rp = method.getAnnotation(RequiredPermission.class);
                        String name = rp.value();

                        // 封装权限对象
                        Permission permission = new Permission();
                        permission.setExpression(expression);
                        permission.setName(name);

                        // 5. 保存权限对象
                        permissionMapper.insert(permission);
                    }
                }
            }
        }
    }

    public Set<String> getExceptionsByEmpId(Long id) {
        return permissionMapper.selectExpsByEmpId(id);
    }
}
